如果你先查出“计算机专业学生”,再查出“数学专业学生”,最后想把这两批学生放进同一张结果表里,这时就不是连接表,而是把两个查询结果合并。
这种“把结果上下拼起来”的操作,就是 UNION。
一、UNION 到底在做什么
📘 定义
集合运算查询是使用 UNION 将不同查询得到的结果集合并起来,形成一个综合结果集。
💬 人话翻译
不是把两张表拼成更宽,而是把两份查询结果叠在一起,让结果的“行数变多”。
必须记住
UNION 会自动去掉重复行。所以如果两个查询都查到了完全相同的一行,最终结果里只会保留一份。
这样理解
UNION 更像“把两张名单合成一张总名单”,而不是“把两张表按字段对上”。
UNION 的执行感受
1
先执行第一个 SELECT
2
再执行第二个 SELECT
3
把两份结果上下合并
4
自动去掉重复行
二、使用 UNION 之前,先检查两个前提
规则 1:列数必须一致
检查方式
第一个查询返回几列,第二个查询也必须返回几列。不能一个查 2 列,另一个查 3 列。
SELECT sno, sn
FROM s
UNION
SELECT tno, tn
FROM t;规则 2:对应列的数据类型要匹配
不是名字一样,而是位置对应
第一列最好对应编号,第二列最好对应名称。也就是说,对应位置上的数据含义与类型要基本能对得上。
| 位置 | 第一个查询 | 第二个查询 |
|---|---|---|
| 第 1 列 | 学号 | 教师号 |
| 第 2 列 | 姓名 | 姓名 |
一张表把规则说清楚
| 检查项 | 要求 | 不满足时会怎样 |
|---|---|---|
| 返回列数 | 必须相同 | SQL 直接报错 |
| 对应列类型 | 要匹配或兼容 | 可能报错,或结果看起来很怪 |
| 重复行 | UNION 自动去重 | 最终结果不会重复显示 |
三、最容易混淆:UNION 和 JOIN 到底差在哪
UNION
- 纵向拼接结果,行数变多
- 关注的是“两个查询结果能不能合并”
- 常见于“把两类对象放到一起”
JOIN
- 横向连接表,列数变多
- 关注的是“表与表之间靠什么字段关联”
- 常见于“把一张表的编号和另一张表的说明连起来”
💬 一句话区分
UNION 解决“把两个结果放一起”,JOIN 解决“把两张表连起来看”。
四、例 6-56:把两个专业的学生信息合并
题目:查询“计算机”专业的学生信息,再查询“数学”专业的学生信息,将两个查询结果合并成一个结果集。
模拟数据:学生表 s
| sno | sn | age | maj |
|---|---|---|---|
| s1 | 张三 | 18 | 计算机 |
| s2 | 赵琳琳 | 19 | 数学 |
| s3 | 王敏 | 20 | 计算机 |
| s4 | 陈晨 | 21 | 英语 |
| s5 | 李雪 | 18 | 数学 |
SELECT *
FROM s
WHERE maj = '计算机'
UNION
SELECT *
FROM s
WHERE maj = '数学';1
先得到计算机专业学生
2
再得到数学专业学生
3
两份结果上下合并
为什么这题适合用 UNION
两边都来自同一张学生表 s,返回的列也完全一致,区别只是专业条件不同,因此非常适合直接合并。
运行结果
| sno | sn | age | maj |
|---|---|---|---|
| s1 | 张三 | 18 | 计算机 |
| s3 | 王敏 | 20 | 计算机 |
| s2 | 赵琳琳 | 19 | 数学 |
| s5 | 李雪 | 18 | 数学 |
五、例 6-57:把两门课程的统计结果合并
题目:查询课程号为 c1 的课程总分和平均分,再查询课程号为 c2 的课程总分和平均分,将两个查询结果合并成一个结果集。
模拟数据:选课表 sc
| sno | cno | score |
|---|---|---|
| s1 | c1 | 86 |
| s2 | c1 | 88 |
| s1 | c2 | 90 |
| s2 | c2 | 92 |
| s4 | c2 | 69 |
| s3 | c3 | 85 |
SELECT cno AS 课程号,
SUM(score) AS 总分,
AVG(score) AS 平均分
FROM sc
WHERE cno = 'c1'
GROUP BY cno
UNION
SELECT cno AS 课程号,
SUM(score) AS 总分,
AVG(score) AS 平均分
FROM sc
WHERE cno = 'c2'
GROUP BY cno;这题要注意的点
两边虽然都是统计查询,但仍然要保证返回列结构一致。这里两边都返回 3 列:课程号、总分、平均分,所以可以 UNION。
运行结果
| 课程号 | 总分 | 平均分 |
|---|---|---|
| c1 | 174 | 87.00 |
| c2 | 251 | 83.67 |
六、这节最常见的三个易错点
误区 1:把 UNION 当成连接表
错因
学生一看到“合并”就容易想到多表连接。
记法:UNION 是结果对结果的合并,不是表对表的关联。
误区 2:忽略列数与类型
错因
只顾着写两个 SELECT,没有先检查结构是否一致。
这是最容易直接报错的地方。
误区 3:忘记 UNION 会自动去重
错因
学生以为两个查询里重复出现的行会保留两次。
要强调:UNION 默认按集合思维处理。
七、练习
练习 1
下面关于 UNION 的说法,哪一项正确?
A. 它会把两个查询结果上下合并
B. 它会让查询结果的列数一定增加
C. 它必须依赖两张表之间的连接字段
D. 它不会去重
正确答案是 A。UNION 的核心就是把两个结果纵向合并。B 和 C 更像 JOIN 的特点,D 与 UNION 的默认行为相反。
练习 2
使用 UNION 之前,最先应该检查什么?
A. 两边有没有 WHERE
B. 两边是不是同一张表
C. 两边返回列数是否一致、对应列类型是否匹配
D. 两边有没有主键
正确答案是 C。UNION 不要求一定来自同一张表,也不要求必须有主键,但列结构必须能对上。
练习 3
“把学生信息和选课信息根据学号连起来看”更适合使用哪种思路?
A. UNION
B. JOIN
C. EXISTS
D. GROUP BY
正确答案是 B。因为这题是在不同表之间按字段进行关联,属于连接查询,不属于集合合并。